/**
 * 
 * 根据主表id字段进行数据过滤的基类方法，主从类型业务的从表业务可继承该类方法
 * @author : jackson wang
 * @Date   : 2015年10月3日 下午9:47:33
 * @version: 1.0
 * @param <T> 泛型需定义的业务类实体
 */
package org.brisling.base.service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.brisling.base.domain.ListDomain;
import org.brisling.base.domain.RetDomain;
import org.brisling.base.domain.inf.BaseSubDomainInf;
import org.brisling.base.repository.BaseSubRepository;
import org.brisling.common.util.LongUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

public class BaseSubService<T extends BaseSubDomainInf> extends BaseService<T>{

	//定义起始页是否为1
	protected Boolean pageBasedOne=false;
	
	@Autowired
	protected BaseSubRepository<T,Long> baseRepo;
	
	
	@Autowired
	protected void setService(BaseSubRepository<T,Long> baseRepo){
		this.baseRepo = baseRepo;
		super.setService(baseRepo);
	}
		
	/**
	 * 
	 * @param mainId	分类字段值
	 * @param page		分页号
	 * @param pageSize	每页记录数量
	 * @param repo		仓库类
	 * @return	按照total 及  list封装的返回值（easyui列表页面要求）
	 */
	public ListDomain<T> getPagedListDomainByMainId(String mainId,String page,String pageSize
			){
		
		Long _MainId = LongUtil.getLongValue(mainId, null);
		Integer _page = LongUtil.getIntValue(page, 0);
		Integer _pageSize = LongUtil.getIntValue(pageSize, 10);		
		return this.getPagedListDomainByMainId(_MainId, _page, _pageSize);		
	}
	
	/**
	 * 
	 * @param mainId	分类字段值
	 * @param page		分页号
	 * @param pageSize	每页记录数量
	 * @param repo		仓库类
	 * @return	按照total 及  list封装的返回值（easyui列表页面要求）
	 */
	public ListDomain<T> getPagedListDomainByMainId(Long mainId,String page,String pageSize
			){		
		Integer _page = LongUtil.getIntValue(page, 0);
		Integer _pageSize = LongUtil.getIntValue(pageSize, 10);		
		return this.getPagedListDomainByMainId(mainId, _page, _pageSize);		
	}
	
	/**
	 * 
	 * @param mainId	分类字段值
	 * @param page		分页号
	 * @param pageSize	每页记录数量
	 * @param repo		仓库类
	 * @return	按照total 及  list封装的返回值（easyui列表页面要求）
	 */
	public ListDomain<T> getPagedListDomainByMainId(Long mainId,Integer page,Integer pageSize){		
		ListDomain<T> listDomain = new ListDomain<T>();
		//dept为空，返回空值对象
		if(mainId==null){
			listDomain.setTotal(0l);
			listDomain.setRows(new ArrayList<T>());
			return listDomain;
		}
	
		if(!pageBasedOne)
			page -= 1;
		
		PageRequest _pageRequest = this.getPageRequest(page, pageSize, "sortedid");
				
		
		
		Page<T> _usrList = baseRepo.findByMainId(mainId, _pageRequest);		
		
		listDomain.setTotal(_usrList.getTotalElements());
		listDomain.setRows(_usrList.getContent());
		
		return listDomain;		
	}
	
	
	/**
	 * 
	 * @param mainId	分类字段值
	 * @param page		分页号
	 * @param pageSize	每页记录数量
	 * @param repo		仓库类
	 * @return	按照total 及  list封装的返回值（easyui列表页面要求）
	 */
	public List<T> getPagedListByMainId(Long mainId,String page,String pageSize){
		
		Integer _page = LongUtil.getIntValue(page, null);
		Integer _pageSize = LongUtil.getIntValue(pageSize, null);
		return this.getPagedListByMainId(mainId, _page, _pageSize, this.defaultSort);	
	}
	/**
	 * 
	 * @param mainId	分类字段值
	 * @param page		分页号
	 * @param pageSize	每页记录数量
	 * @param repo		仓库类
	 * @return	按照total 及  list封装的返回值（easyui列表页面要求）
	 */
	public List<T> getPagedListByMainId(Long mainId,Integer page,Integer pageSize,Sort sort){		
		Page<T> _usrList =null;
		
		Sort _sort = sort == null?new Sort(new String[]{"sortedid"}):sort;
		
		
		
		PageRequest _pageRequest = this.getPageRequest(page, pageSize, _sort);	
		//dept为空，返回空值对象
		if(mainId==null){			
			_usrList = baseRepo.findAll(_pageRequest);
		}else{		
			_usrList = baseRepo.findByMainId(mainId, _pageRequest);				
		}
		return _usrList.getContent();		
	}
	
	/**
	 * 保存前端传递的json数据集合
	 * @param mainId
	 * @param jsonData
	 * @return
	 */
	protected RetDomain saveList(Long mainId,String jsonData){
		
		List<T> lists = null;
		if(jsonData!=null){
			ObjectMapper mapper = new ObjectMapper();
			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);	
			JavaType _javaType = mapper.getTypeFactory().constructCollectionType(List.class, clazz);
			
			try {
				lists =  mapper.readValue(jsonData, _javaType);
				
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}		
			if(lists!=null && lists.size()>0){
				for(T t:lists){
					t.setMainId(mainId);
				}
			}
		}
		return this.saveList(mainId, lists);
	}
	/**
	 * 保存数据集合
	 * @param mainId
	 * @param lists
	 * @return
	 */
	protected RetDomain saveList(Long mainId,List<T> lists){
		
		return persistData(mainId,lists);
	}
	
	
	
	/**
	 * 根据主表业务记录，查询子表业务集合，并与传入的子表集合进行比对，生成待删除记录id，生成待保存记录集合
	 * @param mainId	主业务记录id
	 * @param lists		前端传入的子表业务集合
	 * @return	
	 */
	protected RetDomain persistData(Long mainId,List<T> lists){
		
		//判断主表记录是否为空
		if(mainId!=null){
			
			
			//判断传入记录值是否为空
			if(lists !=null && lists.size()>0){
				
				//查询已有记录集合
				List<T> existLists = baseRepo.findByMainId(mainId);
			
				//已有数据记录不为空
				if(existLists!=null && existLists.size()>0){
					
					//初始化已有记录map对象
					Map<Long,T> existMap = new HashMap<Long,T>();
					for(T et:existLists){
						existMap.put(et.getId(), et);
					}
					
					for(T it:lists){		
						
												
						if(it.getId()!=null){
							//判断传入数据与已有数据的id匹配情况
							if(existMap.containsKey(it.getId())){
								existMap.remove(it.getId());
							}
						}						
					}
					
					String ids = null;
					//判断是否存在已被删除数据
					if(existMap.size()>0){
						for(Map.Entry<Long, T> entry:existMap.entrySet()){
							ids=ids==null?entry.getValue().getId()+"":ids+","+entry.getValue().getId();
						}
					}
					
					if(ids!=null){
						this.delRows(null, ids);
					}
				}
				
				//子表已有数据为空,直接保存子表记录
				return super.saveList(lists);
			}else{
				//传入记录为空，删除以当前主表id为外键的所有记录
				String sql = String.format("delete from %1$s where mainId = %2$s", this.moduleName,mainId);
				super.executeNativeDelOrUpdate(sql);
			}
		}
		
		return null;
	}
	
}
